#define _GNU_SOURCE
#include "daemon_sub_process.h"
#include "unistd.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/reboot.h>
#include <stdlib.h>
#include <string.h>
#include "log.h"


/**
 *  初始化子进程    
 */
SubProcess  *daemon_sub_process_init(char *sub_cmd)
{
     //1  创建子进程结构体 
     sub_process_t *sub_process = (sub_process_t *)malloc(sizeof(sub_process_t));
     //2  初始化子进程结构体
     sub_process->sub_cmd=malloc(strlen(sub_cmd)+1);
     strcpy(sub_process->sub_cmd,sub_cmd);
     sub_process->pid=-1;
     sub_process->failed_count=0;

     return sub_process;
}


/**
 *  检查并启动子进程
 *  //1  检查子进程的生死  pid!=-1 曾经活过  waitpid !=-1  还活着
 *  //2  之后部分都是子进程已死   
 *    u是不是横死 waitpid status !=0   则c子进程是横死的 failed_count++  如果超过阈值则进行重启设备
 *  //3  i开始启动  fork 
 *  //4  父进程 打印 
 *  //5   子进程  执行程序  execve()
 *  //6  子进程   _exit()
 */
int daemon_sub_process_check_and_start(SubProcess *sub_process)
{   log_info("检查子进程 %s",sub_process->sub_cmd); 
    //1  检查子进程的生死  pid!=-1 曾经活过  waitpid !=-1  还活着
    int status;
    if(sub_process->pid!=-1 && waitpid(sub_process->pid,&status,WNOHANG ) !=-1 )
    {
        return 0;
    }
    //2  是不是横死 waitpid status !=0   则c子进程是横死的 failed_count++  如果超过阈值则进行重启设备
    if(status!=0)
    {
        sub_process->failed_count++;
        if(sub_process->failed_count>MAX_FAILED_COUNT)
        {
            reboot(RB_AUTOBOOT); //重启设备
        }
    }
    // 3 拉活  开始启动  fork 
    log_info("启动子进程 %s",sub_process->sub_cmd); 
     pid_t pid =fork();
     if(pid>0)
     {  //父进程
        sub_process->pid=pid;
        log_info("启动子进程中.. %s ",sub_process->sub_cmd);
     }
     else{
          //5   子进程  执行程序  execve()
          char *args[3]={EXE_NAME,sub_process->sub_cmd,NULL};
          char *env[1]={NULL};
          int ret= execve(EXE_NAME,args,env);
          if(ret==-1)
          {
              log_error("启动子进程 %s 失败",sub_process->sub_cmd);
              _exit(EXIT_FAILURE);
          }

     }
     return 0;

}

/**
 * 结束子进程
 * 
 */
void daemon_sub_process_stop(SubProcess *sub_process)
{
    kill(sub_process->pid,SIGTERM);
    waitpid(sub_process->pid,NULL,0);
    sub_process->pid=-1;
    sub_process->failed_count=0;
    log_info("结束子进程 %s ",sub_process->sub_cmd);

}